Skip to content

🤖 perf: hide in-progress line, fade completed lines in temporally#3221

Open
ammar-agent wants to merge 12 commits intomainfrom
streaming-block-fade-r1
Open

🤖 perf: hide in-progress line, fade completed lines in temporally#3221
ammar-agent wants to merge 12 commits intomainfrom
streaming-block-fade-r1

Conversation

@ammar-agent
Copy link
Copy Markdown
Collaborator

@ammar-agent ammar-agent commented May 2, 2026

Summary

Hide the in-progress visual line entirely (no partial obfuscation), then fade in each completed line as a unit at the moment its visual row wraps to the next. The trigger is rendered geometry (offsetHeight growth), so it tracks visual rows in the user's viewport — not the AST/HAST tree.

Mental model

Given lines A → B → C in the rendered transcript:

  • While B is partially typed, the user sees only A. B is hidden — no semi-transparent in-progress text, no partial-word obfuscation.
  • When B's visual row completes (text wraps to row C, or stream ends), B fades in over ~250ms. No tear, no jitter, no horizontal stagger.

This is the user's framing verbatim:

It needs to be viewport-aware. We don't care about lines as they're emitted by the model, we care about lines as they're displayed to the user in the transcript.

Given 3 lines A, B, C — A fully loaded, B partially loaded, C not yet arrived — the user sees A. Later, B completes its visual line and C starts streaming in. At that point, fade-in B without visual tear or jitter.

Implementation

CSS (globals.css)

@property --reveal-y {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

@media (prefers-reduced-motion: no-preference) {
  .markdown-content[data-streaming="true"] {
    -webkit-mask-image: linear-gradient(
      180deg,
      black 0%,
      black calc(100% - 1.6em - var(--reveal-y, 0px) - 0.4em),
      transparent calc(100% - 1.6em - var(--reveal-y, 0px))
    );
    mask-image: linear-gradient( /* ...same... */ );
  }
}

A linear-gradient mask hides the bottom 1.6em (~1 visual line at line-height 1.6). A thin 0.4em fade band right above the boundary softens the edge so completed lines don't snap with a hard cutoff. --reveal-y is an extra offset that pushes the transparent strip upward; resting value is 0px (only the in-progress line is hidden).

JS (TypewriterMarkdown.tsx)

A useLayoutEffect registers a ResizeObserver on the markdown root. When offsetHeight grows by Δ, el.animate() pulses --reveal-y from Δ0 over 250ms. During the pulse, the just-revealed strip is initially also covered by the mask, then is uncovered as the property animates back — producing a temporal fade-in.

Custom-property animation requires the @property declaration so the syntax <length> is interpolatable. WAAPI is preferred over CSS transitions because the start value depends on the runtime delta; once started, the animation runs on the compositor thread.

ResizeObserver presence is guarded for happy-dom test environments; real Electron Chromium always has it.

Why this is genuinely viewport-aware

  • Trigger is rendered geometry, not AST. Height growth happens whenever a visual row wraps — regardless of whether the source is one paragraph wrapping to N rows, N paragraphs of one row each, or a mix.
  • Width-driven re-wraps participate. Sidebar collapse, window resize, and zoom all change offsetHeight, so the fade naturally fires at the right moments.
  • <br> boundaries (reasoning content's preserveLineBreaks) work the same. Each break that adds height triggers a fade.
  • Source-emitted line breaks don't matter. If the model emits one giant paragraph that wraps to 8 visual rows, the user sees 8 fade-ins as the rows fill in.

Validation

  • make typecheck (clean rebuild, no incremental cache): passes.
  • make lint: passes.
  • make fmt-check: passes.
  • bun test src/browser/features/Messages/: 71 pass.

The existing data-streaming gating test (live → "true", replay/completed → absent) is the load-bearing invariant for the CSS rule; it remains as-is.

Risks

Low.

  • Lifecycle: ResizeObserver is disconnected on stream end / unmount; in-flight WAAPI animations are cancelled. Cancelled custom-property animations snap --reveal-y back to its declared initial-value: 0px.
  • Multiple rapid wraps: in-flight pulses are cancelled before a new one starts, so the most recent delta wins. Brief streams of small wraps won't stack into longer-than-250ms fades.
  • Browser support: @property and WAAPI custom-property animation require Chromium ≥ 85 / Safari ≥ 16.4 / Firefox ≥ 128. Mux ships in Electron with modern Chromium; non-supporting runtimes silently skip the animation (catch + null).
  • Stream-end snap: when data-streaming is removed, the previously-hidden in-progress line snaps to visible. The smoothing engine has finished revealing characters by then, so the snap is barely perceptible.
  • Layout-only re-wraps during streaming (sidebar toggle, window resize) trigger a brief fade — acceptable artifact, and the user's attention is already on layout movement at that moment.

Pains

Four iterations to land on the right level of abstraction:

Iteration history
  1. Per-block CSS fade-in (<p>/<h*>/<li> fade once at mount): worked for new paragraphs but invisible inside thinking blocks (typically one paragraph — animation fires once at mount, then text grows silently inside the same <p>).
  2. Per-word blur fade-in via a rehype plugin: visible inside thinking blocks, but words on the same visual row mounted at slightly staggered times because deltas arrive token-by-token, creating a left-to-right shimmer.
  3. Per-AST-line wrap (one span per HAST text node): killed the horizontal shimmer but had the original problem in reverse — a single <p> wrapping to N visual rows is one span, and once mounted, in-place text growth fires no fade.
  4. Static bottom-edge gradient mask (the previous commit on this branch): viewport-aware in the sense that it operated on rendered geometry, but it obfuscated the in-progress line at low opacity instead of hiding it cleanly. User feedback: "The last line of streaming text is partially obfuscated due to some shadow gradient. I'm not seeing a smooth fade in of the last line text."

The current design (this commit) hides the in-progress line entirely with a sharp clip, and uses JS to pulse a CSS custom property when the rendered height grows — giving a temporal fade-in keyed to actual visual-row events. Each iteration's commit is preserved in the branch history for context.


Generated with mux • Model: anthropic:claude-opus-4-7 • Thinking: max • Cost: $85.42

Adds a soft, GPU-cheap fade-in to each newly-mounted top-level markdown
block while a message is streaming. Maps user's mental model of
"line-by-line" onto markdown blocks: paragraph, heading, list item,
fence, blockquote, table, hr — fires once per new block at mount.

Mechanics
- TypewriterMarkdown sets data-streaming="true" on its wrapper while the
  message is streaming. Absent (not "false") on completed/replayed
  messages so the CSS rule cannot match historical transcripts.
- MarkdownCore appends "streamdown-root" to the className passed through
  to Streamdown's root div — a stable CSS hook with no extra wrapper.
- globals.css adds a keyframes + block-level selector list scoped via
  prefers-reduced-motion. Inline elements (<strong>/<em>/<a>) are
  intentionally excluded because parseIncompleteMarkdown can transiently
  insert/remove them as remend repairs unterminated tokens.

Why this works
- Streamdown keys each block by useId+index and wraps it in React.memo,
  so existing blocks are reconciled in place when their content grows.
  Only newly-arriving top-level blocks mount fresh — and CSS animation
  on a freshly-mounted child fires exactly once at mount.
- No JS bookkeeping, no render-phase work, no prop changes.

Per-character pacing inside SmoothTextEngine still operates inside each
block; the new fade-in layer is purely additive at block boundaries.
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94ae3801ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Messages/TypewriterMarkdown.tsx Outdated
Codex P2 on PR #3221: replay rows are emitted with isStreaming=true
and streamPresentation.source="replay" while the backend rebuilds
history on reconnect. Gating data-streaming on isStreaming alone
would set the attribute and animate every block of every replayed
message — exactly what we wanted to avoid.

Compute isLiveStreaming = isStreaming && streamSource !== "replay"
and gate the data-streaming attribute on that. Completed messages
already have isStreaming=false, so the attribute is naturally absent
in their case too.

Test extended to assert all three cases: live → "true", replay → absent,
completed → absent.
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed your P2: data-streaming is now gated on isStreaming && streamSource !== "replay" (see new comment block in TypewriterMarkdown.tsx:74-82). Replay rows that arrive with isStreaming=true during reconnect/history-replay no longer match the CSS selector. Test extended to cover all three cases: live → "true", replay → absent, completed → absent.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Replace the per-block fade-in (which fired only once per paragraph at
mount, then text grew silently inside) with a per-word blur-fade-in.

Mechanism:
- rehypeSplitWordsForFade walks the HAST tree and wraps each
  whitespace-bounded word in <span class="sd-word">. Skips inside
  <pre>/<code>/KaTeX/Mermaid subtrees so code, math, and diagrams
  stay structurally intact.
- MarkdownCore swaps in this rehype plugin only while
  parseIncompleteMarkdown=true (i.e., during streaming) — completed/
  static markdown still renders without word spans (no extra DOM weight).
- globals.css replaces the per-block keyframes with sd-word-blur-in
  (filter: blur(6px) → blur(0), opacity 0 → 1, 500ms ease-out).
  Still gated on [data-streaming="true"] and prefers-reduced-motion.

Why per-word
- The user reported the prior per-block effect was invisible in
  thinking blocks (which are typically a single paragraph — block
  fade-in fires once at mount, then text grows silently inside the
  same <p>). Per-word also animates inside an already-mounted block:
  each new whitespace boundary mounts a fresh span and triggers a
  fade for that word and only that word.
- Stable identity at every word position: as text grows from "Hel" →
  "Hello", react-markdown reconciles the same span in place; only
  fresh whitespace boundaries mount new spans. Completed words stay
  static while only new words fade in.

Tests
- New rehypeSplitWordsForFade.test.ts covers the core invariants:
  word/whitespace tokenization, partial trailing word, empty input,
  pre/code skip, KaTeX skip, recursion into inline (<strong>/<em>).
@ammar-agent ammar-agent changed the title 🤖 perf: per-block fade-in for streaming markdown (demo) 🤖 perf: per-word blur-fade-in for streaming markdown (demo) May 2, 2026
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Pivoted the design after self-dogfood feedback. The previous per-block fade-in was invisible inside thinking blocks (typically one paragraph — the block fade fires once at mount, text grows silently inside).

Now uses per-word blur-fade-in via a small rehype plugin (rehypeSplitWordsForFade) that wraps each whitespace-bounded word in <span class="sd-word">. Stable identity per word position keeps completed words static while only newly-crossed whitespace boundaries mount fresh spans → CSS animation fires once per new word.

Skips <pre>/<code>/KaTeX/Mermaid subtrees so code, math, and diagrams stay structurally intact. Streaming-only — completed transcripts render without word spans (no DOM bloat). Still gated on data-streaming="true" (live, not replay) and prefers-reduced-motion.

7 new tests in rehypeSplitWordsForFade.test.ts cover the core invariants.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ammar-agent and others added 5 commits May 1, 2026 23:26
Upstream regression: @smithy/util-retry@4.3.7 was published at
2026-05-02T04:09:26Z with workspace:^ refs that escaped the smithy
monorepo. Any lockfile-free bun install (used by both
scripts/check-bench-agent.sh and scripts/smoke-test.sh — which mimic
'bun x mux@latest' for end users) fails to resolve those refs.

Reproduction outside this repo:
  mkdir t && cd t
  echo '{"dependencies":{"@aws-sdk/credential-providers":"^3.940.0"}}' > package.json
  bun install --ignore-scripts
  # → 'Workspace dependency "@smithy/types" not found'

This breaks every PR opened/pushed after 04:09Z (PR #3219 was lucky to
merge ~30 min before). Add an npm-style overrides pin to <=4.3.6 (the
last known-good release, 2026-04-28) until smithy republishes.

Verified locally: 'bash scripts/check-bench-agent.sh' now passes, and
@smithy/util-retry resolves to 4.3.6 in a fresh lockfile-free install.
Companion to the @smithy/util-retry pin (previous commit). The smoke
test runs 'npm install --no-save <tarball>' in a fresh directory whose
package.json declares only mux as a dep — npm doesn't honor the
tarball's nested npm-shrinkwrap.json for transitive resolution, so
without an override at the smoke-test root, transitive @aws-sdk/*
deps still re-resolve to the latest @smithy/util-retry (4.3.7, broken).

Mirror the workspace package.json's 'overrides' block into the smoke
test's package.json so tarball install behaves identically to a real
'bun x mux@latest' user environment.

Verified locally: smoke test now passes end-to-end (server boots,
healthcheck, oRPC HTTP + WebSocket tests all green) with the override
correctly forcing @smithy/util-retry to 4.3.6.
User feedback: the 6px blur was a touch too pronounced. 3px keeps the
soft entry feel while letting word shapes resolve faster — closer to a
Grok-style settle than a heavy reveal.
User feedback: per-word fade caused horizontal jitter inside a single
visual row because words within the same paragraph mounted at slightly
different times (deltas arrive token-by-token), so each row read as a
shimmer instead of a coherent reveal.

Switch the unit from word to line. The rehype plugin now wraps each
text node in a single <span class="sd-line"> instead of splitting on
whitespace. As text grows inside an existing span, react-markdown
reconciles in place — no remount, no re-fade. A new fade only fires
when a real boundary is crossed:
  - new paragraph (new <p> mounts → its first text-node span mounts)
  - new <br> (reasoning content with preserveLineBreaks=true runs
    remarkBreaks, which converts \n → <br>; each text node between
    breaks is a separate line span)
  - new list item, table cell, blockquote line, etc.

Renamed plugin/file/test/class for clarity:
  rehypeSplitWordsForFade → rehypeWrapLinesForFade
  .sd-word → .sd-line
  @Keyframes sd-word-blur-in → sd-line-blur-in

Behavior unchanged for skip rules: <pre>/<code>/KaTeX/Mermaid subtrees
are still excluded. Blur duration (500ms) and intensity (3px) preserved.

Long single paragraphs that grow without internal newlines (the rare
case for long-form reasoning) now grow silently inside one line span —
which is a minor regression on word-by-word visibility but a clear win
on horizontal jitter, per user direction.
Replace the per-line span-wrapping rehype plugin with a CSS mask gradient
on the streaming markdown wrapper. The mask operates on rendered geometry
rather than the AST/HAST tree, so:

- A long paragraph that wraps to N visual rows is treated identically to
  N paragraphs of one row each — what matters is the bottom edge.
- Source-emitted line breaks no longer affect the fade; only what the
  user sees in the transcript does.
- Per-word horizontal jitter goes away (no DOM splitting at all).

The bottom 2em of every live streaming message is masked with a
linear-gradient from black to transparent. As the smoothing engine
reveals characters and the message grows, each new visual row emerges
from the gradient zone (transparent at the bottom) and settles into
solid as it scrolls upward. GPU-accelerated, no JS, no measurement, no
edge cases on reflow.

Net diff: ~−240 LoC (delete plugin + test, simplify MarkdownCore).

Co-authored-by: Mux <noreply@coder.com>
@ammar-agent ammar-agent changed the title 🤖 perf: per-word blur-fade-in for streaming markdown (demo) 🤖 perf: viewport-aware mask gradient for streaming fade-in May 2, 2026
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Pivoted from per-AST-line span wrapping to a viewport-aware bottom-edge mask gradient. The mask operates on rendered geometry, so it tracks visual rows in the transcript rather than AST/HAST text nodes — fixing both prior iterations' weakness (per-line missed long-paragraph wrap-to-N-rows; per-word had horizontal jitter).

Net diff: ~−240 LoC. The rehype plugin and its test are deleted. Streaming markdown now goes through REHYPE_PLUGINS_BASE (no streaming-specific variant). The data-streaming gating on TypewriterMarkdown is unchanged (still live-only, not replay).

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The prior static gradient mask obfuscated the line currently being typed
at low opacity, so users saw partial words at varying transparency. Pivot
to: hide the in-progress line entirely, then fade in each completed line
as a unit at the moment its visual row wraps to the next.

Mental model (rendered transcript A → B → C):
- While B is partially typed, the user sees only A. B is hidden.
- When B's visual row completes (text wraps to row C), B fades in over
  ~250ms with no horizontal stagger, no tear, no jitter.

Implementation:

CSS (globals.css)
- Sharp linear-gradient mask hides the bottom 1.6em (~1 visual line at
  line-height 1.6). A 0.4em fade band right above the boundary softens
  the edge.
- New `@property --reveal-y` (typed <length>, initial 0px) is an extra
  offset that pushes the transparent strip upward.

JS (TypewriterMarkdown.tsx)
- ResizeObserver on the markdown root tracks rendered height growth (the
  signal that maps directly to visual rows in the user's viewport — not
  AST/HAST).
- On any positive delta, Element.animate() pulses --reveal-y from
  `delta` → 0 over 250ms. The mask gradient sweeps past the new
  content, fading it in temporally.
- ResizeObserver presence is guarded so happy-dom test environments
  degrade silently; real Chromium always has it.

Why this is genuinely viewport-aware:
- Trigger is rendered geometry. A long paragraph wrapping to N visual
  rows reveals one row at a time; one AST text node doesn't fool the
  reveal. Width-driven re-wraps from sidebar collapse, window resize,
  and zoom all participate naturally because they change offsetHeight.

Co-authored-by: Mux <noreply@coder.com>
@ammar-agent ammar-agent changed the title 🤖 perf: viewport-aware mask gradient for streaming fade-in 🤖 perf: hide in-progress line, fade completed lines in temporally May 2, 2026
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Pivot from static gradient → JS-driven temporal fade. The prior commit's gradient obfuscated the in-progress line at low opacity; this commit hides it sharply with a mask, then pulses a @property --reveal-y custom property via Element.animate() when ResizeObserver reports height growth, fading completed lines in over 250ms.

Trigger is rendered geometry (offsetHeight change), so visual-row wraps inside long paragraphs participate (the prior per-AST-line approach missed those). ResizeObserver is guarded for happy-dom; real Electron Chromium always has it.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e73af7c023

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/styles/globals.css
The mask was unconditionally hiding the bottom 1.6em (~1 visual line),
which blanked out short replies and stream starts before the first
wrap. Codex P1: 'users can see a blank assistant message until a
second line wraps or the stream completes, which makes live streaming
look stalled'.

Gate the mask on a new `data-stream-hide-tail` attribute, set by JS
only when rendered height is at least ~1.5 line-heights (between 1 and
2 lines). Below that, the message renders fully visible. The threshold
is computed from the element's actual computed line-height so it
scales with font-size and line-height overrides.

Also skip the WAAPI pulse on the first-time threshold crossing
(1 line → 2 lines): the about-to-be-completed first line was already
visible without a mask, so a pulse would briefly hide and re-fade it
in (a flicker). Subsequent wraps (2+ lines stable, growing) still
pulse normally.

Co-authored-by: Mux <noreply@coder.com>
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed the P1: the mask is now gated on a new data-stream-hide-tail attribute that JS toggles only when rendered height is at least ~1.5 line-heights. Below that (single-line streams, stream starts), no mask — the message renders fully visible. The threshold is computed from the element's getComputedStyle().lineHeight so it scales with font-size overrides.

Also skipped the WAAPI pulse on the first-time threshold crossing — the about-to-be-completed first line was already visible without the mask, so a pulse would briefly hide and re-fade it (flicker). Subsequent wraps (2+ lines stable, growing) still pulse normally.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 108791d195

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/styles/globals.css Outdated
`el.toggleAttribute(name, force)` sets the attribute with an EMPTY
value, not "true", so the CSS selector
`[data-stream-hide-tail="true"]` never matched and the mask was
never applied. Use a presence selector `[data-stream-hide-tail]`
instead. Codex P1.

Co-authored-by: Mux <noreply@coder.com>
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Fixed: switched to presence selector [data-stream-hide-tail] since el.toggleAttribute() sets the attribute with an empty value (not "true").

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 031f6892ab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/smoke-test.sh Outdated
Upstream published @smithy/util-retry@4.3.8 ~32min after the broken
4.3.7, fixing the workspace:^ resolution failure. Verified clean
install of latest in a fresh root works.

Revert:

1. package.json: drop the `overrides` block pinning util-retry to
   <=4.3.6.
2. scripts/smoke-test.sh: drop the ROOT_DIR capture and node-script
   that injected the workspace's overrides into the smoke-test root's
   package.json. Restore the original `cat >package.json <<EOF`
   minimal init.

Codex P1: the override injection defeated the purpose of
SKIP_SHRINKWRAP=1 (lockfile-free end-user-equivalent installs), which
exists to catch upstream regressions that `bunx mux@latest` /
`npx` users would hit. By mirroring our root overrides, the smoke
test was masking exactly the failure mode it's designed to catch.
With the upstream fix in place, the workaround is no longer needed
and the smoke test can return to its canonical form.

Co-authored-by: Mux <noreply@coder.com>
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Fixed: reverted both the overrides block in package.json and the override-injection in scripts/smoke-test.sh. Upstream published @smithy/util-retry@4.3.8 ~32min after the broken 4.3.7, fixing the workspace:^ resolution failure — verified clean install of latest in a fresh root works. With the upstream fix in place, the workaround is no longer needed and the smoke test returns to its canonical form (no override injection, so SKIP_SHRINKWRAP=1 again represents lockfile-free end-user-equivalent installs).

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant